package com.ftg.learn.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ftg.learn.common.result.PageResult;
import com.ftg.learn.common.result.Result;
import com.ftg.learn.order.PayTest;
import com.ftg.learn.order.dto.OrderDto;
import com.ftg.learn.order.dto.PageQueryDto;
import com.ftg.learn.order.dto.payDto;
import com.ftg.learn.order.entity.Order;
import com.ftg.learn.order.entity.OrderDetail;
import com.ftg.learn.order.mapper.OrderMapper;
import com.ftg.learn.order.service.OrderDetailService;
import com.ftg.learn.order.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private final OrderDetailService orderDetailService;
    @Autowired
    private final StringRedisTemplate redisTemplate;
    @Autowired
    private final RestTemplate restTemplate;
    @Override
    public Result<PageResult> pageQuery(PageQueryDto queryDto) {
        Page<Order> page = new Page<>(queryDto.getPageNum(), queryDto.getPageSize());
        LambdaQueryWrapper<Order> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery
                .eq(StringUtils.hasText(queryDto.getNumber()),Order::getNumber, queryDto.getNumber())
                .eq(queryDto.getStatus() != 0,Order::getStatus, queryDto.getStatus())
                .eq(StringUtils.hasText(queryDto.getPayType()),Order::getPayType, queryDto.getPayType());
        Page<Order> orderPage = this.baseMapper.selectPage(page, lambdaQuery);
        if(orderPage.getTotal() == 0){
            return Result.build(200, "分页查询成功，无数据", new PageResult(0, null));
        }
        return Result.build(200, "分页查询成功", new PageResult(orderPage.getTotal(), orderPage.getRecords()));
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> createOrder(OrderDto orderDto) {
        Order order=BeanUtil.copyProperties(orderDto,Order.class);
        String number="ORD"+System.currentTimeMillis();
        order.setNumber(number);
        order.setStatus(1);
        order.setPayStatus(0);
        order.setOrderTime(LocalDateTime.now());
        this.save(order);
        List<OrderDetail> orderDetails=orderDto.getOrderDetails();
        for (OrderDetail orderDetail : orderDetails) {
            orderDetail.setOrderId(order.getId());
        }
        boolean result = orderDetailService.saveBatch(orderDetails);
//        redisTemplate.opsForValue().set("order:"+number,number);
//        redisTemplate.expire("order:"+number,15, TimeUnit.MINUTES);\
        if(!result){
            return Result.build(500, "下单失败");
        }
        return Result.build(200, "下单成功", number);
    }
    @Override
    public Result<String> payOrder(payDto payDto) {
        String pay = restTemplate.postForObject("http://56a44593.r8.cpolar.top/api/alipay/pay", payDto, String.class);
        //pay内包含立即支付
        if(pay.contains("立即支付")) {
            LambdaUpdateWrapper<Order> lambdaUpdate = Wrappers.lambdaUpdate();
            lambdaUpdate
                    .eq(Order::getNumber, payDto.getOutTradeNo())
                    .set(Order::getPayStatus, 1)
                    .set(Order::getCheckoutTime, LocalDateTime.now())
                    .set(Order::getStatus, 3);
            this.update(lambdaUpdate);
            return Result.build(200, "支付成功");
        }
        return Result.build(500, "支付失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> deledeById(String orderId) {
        this.removeById(orderId);
        boolean b = orderDetailService.removeByMap(Map.of("order_id", orderId));
        if(b){
            return Result.build(200, "删除成功");
        }
        return Result.build(500, "删除失败");
    }

    @Override
    public Result<String> addOrder(String orderId) {
        LambdaUpdateWrapper<Order> lambdaUpdate = Wrappers.lambdaUpdate();
        lambdaUpdate
                .eq(Order::getNumber, orderId)
                .set(Order::getStatus, 2);
        boolean update = this.update(lambdaUpdate);
        if(update){
            return Result.build(200, "再来一单成功");
        }
        return Result.build(500, "再来一单失败");
    }
}
